package com.yunshangwoniu.core.baseDao.impl;

import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import com.yunshangwoniu.core.AbstractEntity;
import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Component;

import com.yunshangwoniu.core.baseDao.BaseDao;
import com.yunshangwoniu.core.page.Page;
import org.springframework.transaction.annotation.Transactional;

/*
 * dao层的基础组件,继承此组件的组件可以获得 getById saveObject deleteById getByUsername 等方法
 * author chendonglin
 */
@Component("baseDao")
public  class  BaseDaoImpl<T> implements BaseDao<T>
{
	private Logger logger = Logger.getLogger(this.getClass());
	@Resource
	protected SessionFactory sessionFactory;
	@SuppressWarnings("unchecked")
	@Override
	public T getById(Class<?> t,Object id)
	{
		Session session = sessionFactory.getCurrentSession();
		String className = t.getName();
		String[] names = className.split("\\.");
		String tableName = null;
		if(names.length<=1) tableName = className;
		tableName = names[names.length-1];
		String hql = "from tableName t where t.id=?";
		hql = hql.replaceAll("tableName", tableName);
		Query q  = session.createQuery(hql);
		q.setParameter(0, id);
		T t2 = (T)q.uniqueResult();
		
		return t2;
	}
	
	@Override
	@Transactional
	public T save(T t)
	{
		logger.debug("start insert table tableName is "+t.getClass().getSimpleName());
		Session session = sessionFactory.getCurrentSession();
		session.save(t);
		return t;
	}
	
	@Override
	public void deleteById(Class<?> t,Object id)
	{
		Session session = sessionFactory.getCurrentSession();
		String className = t.getName();
		String[] names = className.split("\\.");
		String tableName = null;
		if(names.length<=1) tableName = className;
		tableName = names[names.length-1];
		String hql = "delete tableName t where t.id=?";
		hql = hql.replaceAll("tableName", tableName);
		Query q  = session.createQuery(hql);
		q.setParameter(0, id);
		q.executeUpdate();
	}
	
	@Override
    @Transactional
	@SuppressWarnings("unchecked")
	public T getByUsername(Class<?> t ,Object username)
	{
		Session session = sessionFactory.getCurrentSession();
		String className = t.getName();
		String[] names = className.split("\\.");
		String tableName = null;
		if(names.length<=1) tableName = className;
		tableName = names[names.length-1];
		String hql = "from tableName t where t.username=?";
		hql = hql.replaceAll("tableName", tableName);
		Query q  = session.createQuery(hql);
		q.setParameter(0, username);
		T t2 = (T)q.uniqueResult();

		return t2;
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public T getByName(Class<?> t ,Object name)
	{
		Session session = sessionFactory.getCurrentSession();
		String className = t.getName();
		String[] names = className.split("\\.");
		String tableName = null;
		if(names.length<=1) tableName = className;
		tableName = names[names.length-1];
		String hql = "from tableName t where t.name=?";
		hql = hql.replaceAll("tableName", tableName);
		Query q  = session.createQuery(hql);
		q.setParameter(0, name);
		T t2 = (T)q.uniqueResult();
		
		return t2;
	}
	
	
	@Override
	public long count(Map<String,Object> params,Class<?> c)
	{
		Session session = sessionFactory.getCurrentSession();
		Criteria cr = session.createCriteria(c);
		if(params!=null)
		{
			for(String paramName : params.keySet())
			{
				cr.add(Restrictions.eq(paramName,params.get(paramName)));  
			}
		}
		@SuppressWarnings("unchecked")
		List<T> list = cr.list();
		
		return list!=null?list.size():0L;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public Page<T> query(Page<T> page,Class<?> t)
	{
		Map<String, Object> params = page.getParams();
		Session session = sessionFactory.getCurrentSession();
		long  count =count(params, t);
		List<T> list = null;
		if(count!=0)
		{
			Criteria cr = session.createCriteria(t);
			cr.setFirstResult((int)page.getBeginRecordNum());
			cr.setMaxResults((int)page.getEndRecordNum());
			if(params!=null)
			{
				for(String paramName : params.keySet())
				{
					cr.add(Restrictions.eq(paramName,params.get(paramName)));  
				}
			}
			
			list = cr.list();
		}
		page.pageBuilder(count, list);
		
		return page;
	}
	
	@Override
	public void update(T t)
	{
		Session session = sessionFactory.getCurrentSession();
        AbstractEntity ab = (AbstractEntity)t;
        ab.setLastAccess(System.currentTimeMillis());
        ab.setLastAccessStr(com.yunshangwoniu.core.utils.DateUtils.getCurrentTime());
		session.update(null, t);
	}

	@Override
	public void batchDelete(List<Long> ids, Class<?> c)
	{
		Session session = sessionFactory.getCurrentSession();
		String className = c.getName();
		String[] names = className.split("\\.");
		String tableName = null;
		if(names.length<=1) tableName = className;
		tableName = names[names.length-1];
		String hql="DELETE tableName t WHERE t.id IN (:alist)";  
		hql = hql.replaceAll("tableName", tableName);
		Query query = session.createQuery(hql);  
		query.setParameterList("alist", ids);
		query.executeUpdate();
	}
}
